
/**
 * Copyright(c) 2010 Ceno Techonologies Co., Ltd.
 *
 * History:
 *   15-1-20 下午3:18 Created by lyyang
 */
package com.jade.bss.security.shiro.authc;

        import java.util.ArrayList;
        import java.util.List;

        import com.jade.bss.admin.account.AdminAccount;
        import com.jade.bss.admin.account.AdminAccountManager;
        import com.jade.bss.admin.grant.GrantManager;
        import com.jade.bss.admin.permission.PermissionEntry;
        import com.jade.bss.admin.principal.SimplePrincipal;
        import com.jade.framework.base.context.ApplicationContextUtils;
        import com.jade.framework.cache.CacheService;
        import com.jade.framework.cache.CacheUtils;
        import org.apache.shiro.authc.AuthenticationException;
        import org.apache.shiro.authc.AuthenticationInfo;
        import org.apache.shiro.authc.AuthenticationToken;
        import org.apache.shiro.authc.SimpleAuthenticationInfo;
        import org.apache.shiro.authz.AuthorizationInfo;
        import org.apache.shiro.authz.SimpleAuthorizationInfo;
        import org.apache.shiro.subject.PrincipalCollection;

/**
 * 管理员登录realm
 *
 * @author <a href="mailto:lyyang@ceno.cn">lyyang</a>
 * @version 1.0 15-1-20 下午3:18
 */
public class SysAdminRealm
        extends com.jade.framework.security.shiro.realm.SupportSupermanRealm
{
    public static final String CACHE_KEY_PERM = "security.perms";
    protected AdminAccountManager adminAccountManager = ApplicationContextUtils.getBean("bss_adminAccountManager");
    protected GrantManager grantManager = ApplicationContextUtils.getBean("bss_grantManager");
    protected String systemName = "nb-bss";
    protected CacheService cacheService = ApplicationContextUtils.getBean("system_cacheService");
    private long superManId = 1;

    public SysAdminRealm()
    {
        setAuthenticationTokenClass(SysAdminPasswordToken.class);
    }

    public void setSuperManId(long superManId)
    {
        this.superManId = superManId;
    }

    public void setSystemName(String systemName)
    {
        this.systemName = systemName;
    }

    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
    {
        AdminAccount admin = (AdminAccount) principalCollection.getPrimaryPrincipal();
        List<String> permissions = cacheService.get(
                CacheUtils.joinKey(systemName, CACHE_KEY_PERM, String.valueOf(admin.getId())));
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if (permissions != null) {
            info.addStringPermissions(permissions);
        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException
    {
        SysAdminPasswordToken token = (SysAdminPasswordToken) authenticationToken;
        String userName = token.getUsername();
        AdminAccount admin = adminAccountManager.getAdmin(AdminAccount.DEFAULT_TYPE, userName);
        if (admin == null || admin.getStatus() == AdminAccount.STATUS_SUSPEND) {
            return null;
        }
        setPermissionToCache(admin);
        return new SimpleAuthenticationInfo(admin, admin.getPassword(), getName());
    }

    protected void setPermissionToCache(AdminAccount account)
    {
        List<String> permissions = getPermissions(account);
        cacheService.set(CacheUtils.joinKey(systemName, CACHE_KEY_PERM, String.valueOf(account.getId())), permissions,
                24 * 3600);
    }

    protected List<String> getPermissions(AdminAccount account)
    {
        List<String> permissions = new ArrayList<String>();
        SimplePrincipal principal = new SimplePrincipal();
        principal.setName(String.valueOf(account.getId()));
        principal.setType(SimplePrincipal.TYPE_ADMIN);
        List<PermissionEntry> perList = grantManager.getPermissions(principal);
        if (perList != null) {
            for (PermissionEntry perEntry : perList) {
                permissions.add(perEntry.getName());
            }
        }
        return permissions;
    }

    protected boolean isSuperman(PrincipalCollection principals)
    {
        AdminAccount admin = (AdminAccount) principals.getPrimaryPrincipal();
        return admin != null && admin.getId() == superManId;
    }
}
